<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        .box {
            width: 200px;
            height: 200px;
            background-color: aquamarine;

            position: absolute;
            left: 50px;
            top: 50px;
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>
<script>
    // 需求: 鼠标拖拽盒子移动
    // (1) onmousedown 先按下 => 记录按下的位置
    // (2) onmousemove 再移动 => 盒子跟随鼠标相对于按下的位置移动
    // (3) onmouseup  再松开 => 盒子不在跟随鼠标移动


    // 面向对象:
    // 就是将你的需求抽象成一个对象,然后针对这个对象分析其特征(属性)与行为(方法)--这个对象就称之为类(面向对象)

    // 拖拽操作 = {
    //     拖拽的元素,
    //     拖拽开始(按下时执行的操作),
    //     拖拽移动(移动时执行的操作),
    //     拖拽结束(松开时要执行的操作),
    // }

    // var box = document.querySelector(".box");

    // posX posY如何传递?
    // var posX = null;
    // var posY = null;

    // 多个函数嵌套导致this指向混乱的问题！ (如何让内层函数访问外层函数的this指向)
    // (1) 提前声明中间变量存储this指向,在子函数中使用
    // (2) 使用箭头函数 

    // 最简单的面向对象(字面量对象): 将面向过程中的变量和方法整合到对象中,作为对象的属性和方法

    var drag = {
        target: document.querySelector(".box"),

        // 存储按下的位置
        posX: null,
        posY: null,
        // start: function () {// drag.start()
        //     // this -> drag对象
        //     var _this = this;  // 浅复制  _this引用drag对象的内存地址
        //     this.target.onmousedown = function (e) {
        //         // this -> 事件的this指向绑定事件的元素(box)
        //         e = e || window.event;
        //         _this.posX = e.offsetX;
        //         _this.posY = e.offsetY;
        //         console.log(_this);

        //         _this.move();  // 按下时绑定移动事件
        //         _this.end();  // 按下时绑定松开事件
        //     }
        // },
        start: function () {// drag.start()
            // this -> drag对象
            var _this = this;  // 浅复制  _this引用drag对象的内存地址
            this.target.onmousedown = (function (e) {
                // this -> 事件的this指向绑定事件的元素(box)
                e = e || window.event;
                this.posX = e.offsetX;
                this.posY = e.offsetY;
                console.log(this);

                this.move();  // 按下时绑定移动事件
                this.end();  // 按下时绑定松开事件
            }.bind(this)) // 根据原函数得到新函数, 新函数调用时this->drag  => 将新函数作为事件处理函数
        },
        move: function () { // drag.move();
            // this -> drag对象
            document.onmousemove = (e) => {
                // this -> 事件的this指向绑定事件的元素(document)

                e = e || window.event;

                var x = e.pageX - this.posX;
                var y = e.pageY - this.posY;

                this.target.style.left = x + "px";
                this.target.style.top = y + "px";

            }
        },
        end: function () {
            document.onmouseup = function () {
                document.onmousemove = null;
            }
        }

    }

    drag.start();
    // drag.move();


</script>

</html>